Skip to content

fix: require authentication before wallet and wallet-set creation - #25

Open
memosr wants to merge 1 commit into
circlefin:masterfrom
memosr:fix/missing-auth-wallet-creation
Open

fix: require authentication before wallet and wallet-set creation#25
memosr wants to merge 1 commit into
circlefin:masterfrom
memosr:fix/missing-auth-wallet-creation

Conversation

@memosr

@memosr memosr commented Jun 3, 2026

Copy link
Copy Markdown

Problem

Two endpoints either skip authentication entirely or run privileged Circle SDK calls before the auth check, allowing unauthenticated callers to abuse the app's Circle developer account.

app/api/wallet-set/route.ts (POST)

The handler has no Supabase import and no getUser() call at all. Any unauthenticated HTTP client can create wallet sets in the app's Circle developer account.

app/api/wallet/route.ts (POST)

circleDeveloperSdk.createWallets() is called at line ~46, before the only auth check at line ~66. The auth check also lives inside an inner try/catch explicitly labeled "do not block wallet creation if this fails," so even a failure there doesn't gate the SDK call.

Impact

  • Quota abuse: Each unauthenticated call burns Circle API quota.
  • Resource pollution: Orphaned wallets and wallet sets accumulate in the developer account.
  • Inconsistency: Every other route in the codebase (transfer, payout, deposit, compliance) correctly calls supabase.auth.getUser() at the top and returns 401 before touching any external API. These two are the outliers.

Fix

Move the auth check to the top of each handler, matching the existing pattern used by app/api/wallet/transfer/route.ts and app/api/gateway/deposit/route.ts:

+ import { createClient } from "@/lib/supabase/server";

  export async function POST(req: NextRequest) {
    try {
+     const supabase = await createClient();
+     const { data: { user } } = await supabase.auth.getUser();
+     if (!user) {
+       return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+     }
+
      // ... rest of handler
    }
  }

In wallet/route.ts, the redundant inner createClient() / getUser() block (which only set the userId on the inserted DB record) was also removed — the outer supabase and user are reused instead.

Impact

  • Security: Unauthenticated Circle SDK abuse is no longer possible.
  • Consistency: Both handlers now match the auth pattern used by every other route in this codebase.
  • Risk: Low — no behavior change for authenticated users; unauthenticated callers now get a proper 401.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant